﻿Imports Dokan
Imports System.Collections.Generic
Imports System.Text
Imports Microsoft.Win32
Imports DiscUtils
Imports System.IO
Imports DokanDiskUtilsBridge
Imports System.Windows.Forms

Public Module Module1
    Sub test()

    End Sub
    Function getFSFromPart(ByVal Partition As Partitions.PartitionInfo) As DiscFileSystem
        Dim ret As DiscFileSystem = Nothing
        Dim strm = Partition.Open
        Select Case Partition.BiosType
            Case 7 'NTFS
                ret = New Ntfs.NtfsFileSystem(strm)
            Case 1 Or 4 Or 6 Or 11 Or 12 Or 14  'FAT12, FAT16, and FAT32 (All variations of each)
                ret = New Fat.FatFileSystem(strm)
        End Select
        Return ret
    End Function
    Function createTestFloppy(ByVal filename As String) As Fat.FatFileSystem
        Using fs As FileStream = File.Create(filename)
            Using floppy As Fat.FatFileSystem = Fat.FatFileSystem.FormatFloppy(fs, FloppyDiskType.HighDensity, "TEST FLOPPY")
                ' Use stream...                                                

                Using s As Stream = floppy.OpenFile("foo.txt", FileMode.Create)
                    Dim ts As New StreamWriter(s)
                    ts.AutoFlush = True
                    ts.Write("Hello World!")
                    Return floppy
                End Using
            End Using
        End Using
    End Function
    Function createTestNTFS(ByVal filename As String) As Ntfs.NtfsFileSystem
        Using fs As FileStream = File.Create(filename)
            Dim cap As Long = 50 * 1024 * 1024
            Using floppy As Ntfs.NtfsFileSystem = Ntfs.NtfsFileSystem.Format(fs, "TEST NTFS", Geometry.FromCapacity(cap), 0, Geometry.FromCapacity(cap).TotalSectors)
                ' Use stream...
                Using s As Stream = floppy.OpenFile("foo.txt", FileMode.Create)
                    Dim ts As New StreamWriter(s)
                    ts.AutoFlush = True
                    ts.Write("Hello World!")
                    Return floppy
                End Using
            End Using
        End Using
    End Function
    Function createTestFAT(ByVal filename As String) As Fat.FatFileSystem
        Using fs As FileStream = File.Create(filename)
            Dim cap As Long = 50 * 1024 * 1024
            Using floppy As Fat.FatFileSystem = Fat.FatFileSystem.FormatPartition(fs, "TEST FAT", Geometry.FromCapacity(cap), 0, Geometry.FromCapacity(cap).TotalSectors, 3)
                ' Use stream...
                Return floppy
            End Using
        End Using
    End Function
    Sub Main()
        Dim dn As New Dokan.DokanNet
        Dim Path = ""
        Dim key As String = 0


restart:  'File Selection Process
        Console.WriteLine("Choose a FileSystem: (All except Floppy will be ~50MB)")
        Console.WriteLine("1. NTFS")
        Console.WriteLine("2. 1.44 MB Fat Floppy")
        Console.WriteLine("3. FAT32")
        Console.WriteLine("4. ISO (Read-Only!)")
        'Console.WriteLine("5. Raw Harddisk (All Partitions)")

        key = Console.ReadKey(False).KeyChar
        Console.WriteLine("")
        Select Case key
            Case 1
                Path = "NTFS.fs"
            Case 2
                Path = "FATFLOPPY.fs"
            Case 3
                Path = "FAT.fs"
            Case 4
                Path = "ISO.fs"
            Case 5
            Case Else
                Console.Clear()
                GoTo restart
        End Select
        If My.Computer.FileSystem.FileExists(Path) Then
            Select Case Path
                Case "NTFS.fs"
                    fs = New Ntfs.NtfsFileSystem(file.Open(Path, FileMode.Open, FileAccess.ReadWrite))
                Case "FATFLOPPY.fs"
                    fs = New Fat.FatFileSystem(file.Open(Path, FileMode.Open, FileAccess.ReadWrite))
                Case "FAT.fs"
                    fs = New Fat.FatFileSystem(file.Open(Path, FileMode.Open, FileAccess.ReadWrite))
                Case "ISO.fs"
                    fs = New Iso9660.CDReader(file.Open(Path, FileMode.Open, FileAccess.ReadWrite), True)
            End Select
        Else
            Select Case Path
                Case "NTFS.fs"
                    fs = createTestNTFS(Path)
                Case "FATFLOPPY.fs"
                    fs = createTestFloppy(Path)
                Case "FAT.fs"
                    fs = createTestFAT(Path)
                Case "ISO.fs"
                    Dim builder As New DiscUtils.Iso9660.CDBuilder
                    builder.UseJoliet = True
                    builder.AddDirectory("data")
                    builder.Build(Path)
                    fs = New Iso9660.CDReader(file.Open(Path, FileMode.Open, FileAccess.ReadWrite), True)
            End Select
        End If


        Dim opt As New DokanOptions
        opt.MountPoint = "Z:\"
        opt.DebugMode = True
        opt.UseStdErr = False
        opt.VolumeLabel = fs.VolumeLabel
        opt.NetworkDrive = False
        opt.ThreadCount = 1
        Dim br As New bridge(fs)
        br.log = Sub(txt As String)
                     Console.WriteLine(txt)
                 End Sub
        ' Shell(opt.MountPoint)
        Dim status As Integer = DokanNet.DokanMain(opt, br)
        Select Case status
            Case DokanNet.DOKAN_DRIVE_LETTER_ERROR
                Console.WriteLine("Drvie letter error")
                Exit Select
            Case DokanNet.DOKAN_DRIVER_INSTALL_ERROR
                Console.WriteLine("Driver install error")
                Exit Select
            Case DokanNet.DOKAN_MOUNT_ERROR
                Console.WriteLine("Mount error")
                Exit Select
            Case DokanNet.DOKAN_START_ERROR
                Console.WriteLine("Start error")
                Exit Select
            Case DokanNet.DOKAN_ERROR
                Console.WriteLine("Unknown error")
                Exit Select
            Case DokanNet.DOKAN_SUCCESS
                Console.WriteLine("Success")
                Exit Select
            Case Else
                Console.WriteLine("Unknown status: " & status)
                Exit Select
        End Select
        Console.ReadKey()
    End Sub

    Public Sub CopyStreamContents(ByVal objInput As Stream, ByVal objOutput As Stream)

        ' assert these are the right kind of streams
        If objInput Is Nothing Then Throw New ArgumentNullException("input")
        If objOutput Is Nothing Then Throw New ArgumentNullException("output")
        If Not objInput.CanRead Then Throw New ArgumentException("Input stream must support CanRead")
        If Not objOutput.CanWrite Then Throw New ArgumentException("Output stream must support CanWrite")

        ' skip if the input stream is empty (if seeking is supported)
        If objInput.CanSeek Then If objInput.Length = 0 Then Exit Sub

        ' allocate buffer (if all pre-conditions are met)
        Dim buffer(1023) As Byte
        Dim count As Integer = buffer.Length

        ' iterate read/writes between streams
        Do
            count = objInput.Read(buffer, 0, count)
            If count = 0 Then Exit Do
            objOutput.Write(buffer, 0, count)
        Loop

    End Sub
    Dim cnt = 0
    Dim fcnt = 0
    Dim fs As DiscFileSystem

End Module

Class RFS
    Implements DokanOperations
#Region "DokanOperations member"

    Private TopDirectory As Dictionary(Of String, RegistryKey)

    Public Sub New()
        TopDirectory = New Dictionary(Of String, RegistryKey)()
        TopDirectory("ClassesRoot") = Registry.ClassesRoot
        TopDirectory("CurrentUser") = Registry.CurrentUser
        TopDirectory("CurrentConfig") = Registry.CurrentConfig
        TopDirectory("LocalMachine") = Registry.LocalMachine
        TopDirectory("Users") = Registry.Users
    End Sub

    Public Function Cleanup(ByVal filename As String, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.Cleanup
        Return 0
    End Function

    Public Function CloseFile(ByVal filename As String, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.CloseFile
        Return 0
    End Function

    Public Function CreateDirectory(ByVal filename As String, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.CreateDirectory
        Return -1
    End Function

    Public Function CreateFile(ByVal filename As String, ByVal access As System.IO.FileAccess, ByVal share As System.IO.FileShare, ByVal mode As System.IO.FileMode, ByVal options As System.IO.FileOptions, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.CreateFile
        Return 0
    End Function

    Public Function DeleteDirectory(ByVal filename As String, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.DeleteDirectory
        Return -1
    End Function

    Public Function DeleteFile(ByVal filename As String, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.DeleteFile
        Return -1
    End Function


    Private Function GetRegistoryEntry(ByVal name As String) As RegistryKey
        Console.WriteLine("GetRegistoryEntry : {0}", name)
        Dim top As Integer = name.IndexOf("\"c, 1) - 1
        If top < 0 Then
            top = name.Length - 1
        End If

        Dim topname As String = name.Substring(1, top)
        Dim [sub] As Integer = name.IndexOf("\"c, 1)

        If TopDirectory.ContainsKey(topname) Then
            If [sub] = -1 Then
                Return TopDirectory(topname)
            Else
                Return TopDirectory(topname).OpenSubKey(name.Substring([sub] + 1))
            End If
        End If
        Return Nothing
    End Function

    Public Function FlushFileBuffers(ByVal filename As String, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.FlushFileBuffers
        Return -1
    End Function

    Public Function FindFiles(ByVal filename As String, ByVal files As System.Collections.ArrayList, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.FindFiles
        If filename = "\" Then
            For Each name As String In TopDirectory.Keys
                Dim finfo As New FileInformation()
                finfo.FileName = name
                finfo.Attributes = System.IO.FileAttributes.Directory
                finfo.LastAccessTime = DateTime.Now
                finfo.LastWriteTime = DateTime.Now
                finfo.CreationTime = DateTime.Now
                files.Add(finfo)
            Next
            Return 0
        Else
            Dim key As RegistryKey = GetRegistoryEntry(filename)
            If key Is Nothing Then
                Return -1
            End If
            For Each name As String In key.GetSubKeyNames()
                Dim finfo As New FileInformation()
                finfo.FileName = name
                finfo.Attributes = System.IO.FileAttributes.Directory
                finfo.LastAccessTime = DateTime.Now
                finfo.LastWriteTime = DateTime.Now
                finfo.CreationTime = DateTime.Now
                files.Add(finfo)
            Next
            For Each name As String In key.GetValueNames()
                Dim finfo As New FileInformation()
                finfo.FileName = name
                finfo.Attributes = System.IO.FileAttributes.Normal
                finfo.LastAccessTime = DateTime.Now
                finfo.LastWriteTime = DateTime.Now
                finfo.CreationTime = DateTime.Now
                files.Add(finfo)
            Next
            Return 0
        End If
    End Function


    Public Function GetFileInformation(ByVal filename As String, ByVal fileinfo As FileInformation, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.GetFileInformation
        If filename = "\" Then
            fileinfo.Attributes = System.IO.FileAttributes.Directory
            fileinfo.LastAccessTime = DateTime.Now
            fileinfo.LastWriteTime = DateTime.Now
            fileinfo.CreationTime = DateTime.Now

            Return 0
        End If

        Dim key As RegistryKey = GetRegistoryEntry(filename)
        If key Is Nothing Then
            Return -1
        End If

        fileinfo.Attributes = System.IO.FileAttributes.Directory
        fileinfo.LastAccessTime = DateTime.Now
        fileinfo.LastWriteTime = DateTime.Now
        fileinfo.CreationTime = DateTime.Now

        Return 0
    End Function

    Public Function LockFile(ByVal filename As String, ByVal offset As Long, ByVal length As Long, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.LockFile
        Return 0
    End Function

    Public Function MoveFile(ByVal filename As String, ByVal newname As String, ByVal replace As Boolean, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.MoveFile
        Return -1
    End Function

    Public Function OpenDirectory(ByVal filename As String, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.OpenDirectory
        Return 0
    End Function

    Public Function ReadFile(ByVal filename As String, ByVal buffer As Byte(), ByRef readBytes As UInteger, ByVal offset As Long, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.ReadFile
        Return -1
    End Function

    Public Function SetEndOfFile(ByVal filename As String, ByVal length As Long, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.SetEndOfFile
        Return -1
    End Function

    Public Function SetAllocationSize(ByVal filename As String, ByVal length As Long, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.SetAllocationSize
        Return -1
    End Function

    Public Function SetFileAttributes(ByVal filename As String, ByVal attr As System.IO.FileAttributes, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.SetFileAttributes
        Return -1
    End Function

    Public Function SetFileTime(ByVal filename As String, ByVal ctime As DateTime, ByVal atime As DateTime, ByVal mtime As DateTime, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.SetFileTime
        Return -1
    End Function

    Public Function UnlockFile(ByVal filename As String, ByVal offset As Long, ByVal length As Long, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.UnlockFile
        Return 0
    End Function

    Public Function Unmount(ByVal info As DokanFileInfo) As Integer Implements DokanOperations.Unmount
        Return 0
    End Function

    Public Function GetDiskFreeSpace(ByRef freeBytesAvailable As ULong, ByRef totalBytes As ULong, ByRef totalFreeBytes As ULong, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.GetDiskFreeSpace
        freeBytesAvailable = 512 * 1024 * 1024
        totalBytes = 1024 * 1024 * 1024
        totalFreeBytes = 512 * 1024 * 1024
        Return 0
    End Function

    Public Function WriteFile(ByVal filename As String, ByVal buffer As Byte(), ByRef writtenBytes As UInteger, ByVal offset As Long, ByVal info As DokanFileInfo) As Integer Implements DokanOperations.WriteFile
        Return -1
    End Function

#End Region
End Class



